#pragma once
#include <string>
#include <memory> // std::auto_ptr
#include <cstdlib> // std::exit
#include <iostream>
#include <odb/database.hxx>
#include <odb/mysql/database.hxx>
#include "logger.hpp"
#include "user.hxx"
#include "user-odb.hxx"
#include "mysql.hpp"

//使用ODB框架对用户表的操作

namespace zrb
{
    class userTable
    {
    public:  
        using ptr = std::shared_ptr<userTable>;
        userTable(std::shared_ptr<odb::core::database>& db)
            :_db(db)
        {}

        //插入数据
        bool insert(const std::shared_ptr<User>& user)
        {
            try 
            {
                //3.获取事务对象开启事务
                odb::transaction trans(_db->begin());
                _db->persist(*user);
                //4.提交事务
                trans.commit();
            }
            catch (std::exception &e) 
            {
                LOG_ERROR("插入{}用户数据出错：{}",user->nickname(),e.what());
                return false;
            }
            return true;
        }

        //更新数据
        bool update(std::shared_ptr<User>& user)
        {
            try 
            {
                //3.获取事务对象开启事务
                odb::transaction trans(_db->begin());
                _db->update(*user);
                //4.提交事务
                trans.commit();
            }
            catch (std::exception &e) 
            {
                LOG_ERROR("更新{}用户数据出错：{}",user->nickname(),e.what());
                return false;
            }
            return true;
        }

        //查找数据
        std::shared_ptr<User> select_by_user_id(const std::string& user_id)
        {
            std::shared_ptr<User> res;
            try
            {
                //获取事务对象开启事务
                odb::transaction trans(_db->begin());
                typedef odb::query<User> query;
                typedef odb::result<User> result;
                res.reset(_db->query_one<User>(query::user_id == user_id));
                //5. 提交事务
                trans.commit();
            }
            catch (std::exception &e) 
            {
                LOG_ERROR("通过用户id{}查询数据出错：{}",user_id,e.what());
            }
            return res;
        }

        std::shared_ptr<User> select_by_nickname(const std::string& nickname)
        {
            std::shared_ptr<User> res;
            try
            {
                //获取事务对象开启事务
                odb::transaction trans(_db->begin());
                typedef odb::query<User> query;
                typedef odb::result<User> result;
                res.reset(_db->query_one<User>(query::nickname == nickname));
                //5. 提交事务
                trans.commit();
            }
            catch (std::exception &e) 
            {
                LOG_ERROR("通过用户昵称{}查询数据出错：{}",nickname,e.what());
            }
            return res;
        }

        std::shared_ptr<User> select_by_phone(const std::string& phone)
        {
            std::shared_ptr<User> res;
            try
            {
                //获取事务对象开启事务
                odb::transaction trans(_db->begin());
                typedef odb::query<User> query;
                typedef odb::result<User> result;
                res.reset(_db->query_one<User>(query::phone == phone));
                //5. 提交事务
                trans.commit();
            }
            catch (std::exception &e) 
            {
                LOG_ERROR("通过用户号码{}查询数据出错：{}",phone,e.what());
            }
            return res;
        }

        //通过多个用户id进行查找
        std::vector<User> select_multi_id(const std::vector<std::string>& id_list)
        {
            std::vector<User> res;
            try {
                //获取事务对象开启事务
                odb::transaction trans(_db->begin());
                typedef odb::query<User> query;
                typedef odb::result<User> result;

                //生成查询条件
                std::stringstream ss;
                ss << "user_id in (";
                for(const auto str : id_list)
                {
                    ss << "'" << str << "'" <<  ",";
                }
                std::string condition = ss.str();
                condition.pop_back(); //删除掉最后一个,
                condition += ")";

                LOG_DEBUG("查询条件为{}",condition);

                //查询
                result r(_db->query<User>(condition));

                //遍历
                for (auto it = r.begin(); it != r.end(); ++it) 
                {
                    res.push_back(*it);
                }
                //5. 提交事务
                trans.commit();
            }
            catch (std::exception &e) 
            {
                LOG_ERROR("通过用户id列表查询数据出错：{}",e.what());
            }
            return res;
        }


    private:
        std::shared_ptr<odb::core::database> _db; 
    };
}

